// --------------------------------------------------------------------------------------------------------------------
// <copyright file="RibbonTabVisibilityBehaviour.cs" company="Concept Architecture">
//   (c) 2010 Muhammad Umer Farooq
// </copyright>
// <summary>
//   Defines the <seealso cref="RibbonTabVisibilityBehaviour" /> type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Hisaab.Client.Common.Helpers
{
    using System;
    using System.Diagnostics.Contracts;
    using System.Windows;

    using Fluent;

    /// <summary>
    /// Defines the <seealso cref="RibbonTabVisibilityBehaviour"/> type.
    /// </summary>
    public class RibbonTabVisibilityBehaviour
    {
        /// <summary>
        /// Member variable IsVisible
        /// </summary>
        public static readonly DependencyProperty IsVisibleProperty = DependencyProperty.RegisterAttached(
            "IsVisible",
            typeof(Visibility?),
            typeof(RibbonTabVisibilityBehaviour),
            new FrameworkPropertyMetadata(OnVisibilityChanged));

        /// <summary>
        /// Member variable ContextualGroupProperty
        /// </summary>
        public static readonly DependencyProperty ContextualGroupProperty = DependencyProperty.RegisterAttached(
            "ContextualGroup",
            typeof(RibbonContextualTabGroup),
            typeof(RibbonTabVisibilityBehaviour));

        /// <summary>
        /// Member variable FocusProperty
        /// </summary>
        public static readonly DependencyProperty FocusProperty = DependencyProperty.RegisterAttached(
            "Focus",
            typeof(bool?),
            typeof(RibbonTabVisibilityBehaviour));

        /// <summary>
        /// Member variable ViewModelProperty
        /// </summary>
        public static readonly DependencyProperty ViewModelProperty = DependencyProperty.RegisterAttached(
            "ViewModel",
            typeof(object),
            typeof(RibbonTabVisibilityBehaviour));

        /// <summary>
        /// Gets the is visible.
        /// </summary>
        /// <param name="element">The element.</param>
        /// <returns>Value of the <c>IsVisible</c> property or <c>null</c> if not set.</returns>
        public static Visibility? GetIsVisible(DependencyObject element)
        {
            Contract.Requires<ArgumentNullException>(element != null);

            return (Visibility?)element.GetValue(IsVisibleProperty);
        }

        /// <summary>
        /// Sets the is focused.
        /// </summary>
        /// <param name="element">The element.</param>
        /// <param name="value">The value.</param>
        public static void SetIsVisible(DependencyObject element, Visibility? value)
        {
            Contract.Requires<ArgumentNullException>(element != null);
            element.SetValue(IsVisibleProperty, value);
        }

        /// <summary>
        /// Gets the contextual group.
        /// </summary>
        /// <param name="element">The element.</param>
        /// <returns>Ribbon contextual tab group item</returns>
        public static RibbonContextualTabGroup GetContextualGroup(DependencyObject element)
        {
            Contract.Requires<ArgumentNullException>(element != null);

            return (RibbonContextualTabGroup)element.GetValue(ContextualGroupProperty);
        }

        /// <summary>
        /// Sets the contextual group.
        /// </summary>
        /// <param name="element">The element.</param>
        /// <param name="value">The value.</param>
        public static void SetContextualGroup(DependencyObject element, RibbonContextualTabGroup value)
        {
            Contract.Requires<ArgumentNullException>(element != null);

            element.SetValue(ContextualGroupProperty, value);
        }

        /// <summary>
        /// Gets the focus.
        /// </summary>
        /// <param name="element">The element.</param>
        /// <returns>Value of the <c>IsVisible</c> property or <c>null</c> if not set.</returns>
        public static bool? GetFocus(DependencyObject element)
        {
            Contract.Requires<ArgumentNullException>(element != null);

            return (bool?)element.GetValue(FocusProperty);
        }

        /// <summary>
        /// Sets the focus.
        /// </summary>
        /// <param name="element">The element.</param>
        /// <param name="value">The value.</param>
        public static void SetFocus(DependencyObject element, bool? value)
        {
            Contract.Requires<ArgumentNullException>(element != null);
            element.SetValue(FocusProperty, value);
        }

        /// <summary>
        /// Gets the focus.
        /// </summary>
        /// <param name="element">The element.</param>
        /// <returns>Value of the <c>IsVisible</c> property or <c>null</c> if not set.</returns>
        public static object GetViewModel(DependencyObject element)
        {
            Contract.Requires<ArgumentNullException>(element != null);

            return element.GetValue(ViewModelProperty);
        }

        /// <summary>
        /// Sets the focus.
        /// </summary>
        /// <param name="element">The element.</param>
        /// <param name="value">The value.</param>
        public static void SetViewModel(DependencyObject element, object value)
        {
            Contract.Requires<ArgumentNullException>(element != null);
            element.SetValue(ViewModelProperty, value);
        }

        /// <summary>
        /// Called when [visibility changed].
        /// </summary>
        /// <param name="d">The d.</param>
        /// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
        private static void OnVisibilityChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var contextualGroup = GetContextualGroup(d);
            if (contextualGroup != null && contextualGroup is RibbonContextualTabGroup)
            {
                var group = (RibbonContextualTabGroup)contextualGroup;
                var newVisibility = (Visibility)e.NewValue;
                group.Visibility = newVisibility;
                var focus = GetFocus(d);
                if (newVisibility == Visibility.Visible)
                {
                    if (focus.HasValue && focus.Value)
                    {
                        group.Focus();
                    }
                }
            }
        }
    }
}